﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FlashCards.Dto;

namespace FlashCards.Service.Extensions
{
    public static class ConversionExtensions
    {
        #region DTO to ENTITY

        #region Creating new

        public static Model.RepeatItem ToEntity(this RepeatItem dtoItem)
        {
            var entityItem = new Model.RepeatItem
            {
                RepeatMark = dtoItem.RepeatMark,
                FlashcardId = dtoItem.FlashcardId,
                IsCopied = dtoItem.IsCopied
            };

            return entityItem;
        }

        public static Model.Repeat ToEntity(this Repeat dtoRepeat)
        {
            var entityRepeat = new Model.Repeat
            {
                FlashcardSetId = dtoRepeat.FlashcardSetId,
                UserId = dtoRepeat.UserId,
                RepeatDate = dtoRepeat.RepeatDate,
            };

            foreach (var item in dtoRepeat.Items)
                entityRepeat.RepeatItems.Add(item.ToEntity());

            return entityRepeat;
        }
        
        public static Model.FlashcardPartType ToEntity(this FlashcardPartType dtoPartType)
        {
            var entityType = new Model.FlashcardPartType
            {
                FlashcardPartTypeId = dtoPartType.Id,
                Name = dtoPartType.Name
            };

            return entityType;
        }

        public static Model.FlashcardPart ToEntity(this FlashcardPart dtoPart)
        {
            var entityPart = new Model.FlashcardPart
            {
                Data = dtoPart.Data,
                DateModified = dtoPart.DateModified,
                FlashcardPartId = dtoPart.Id,
                TypeId = dtoPart.Type.Id,
            };

            return entityPart;
        }

        public static Model.Flashcard ToEntity(this Flashcard dtoFlashcard)
        {
            var entityFlashcard = new Model.Flashcard
            {
                DateModified = dtoFlashcard.DateModified,
                Definition = dtoFlashcard.Definition.ToEntity(),
                FlashcardId = dtoFlashcard.Id,
                FlashcardSetId = dtoFlashcard.FlashcardSetId,
                Term = dtoFlashcard.Term.ToEntity(),
            };

            return entityFlashcard;
        }

        public static Model.FlashcardSet ToEntity(this FlashcardSet dtoSet)
        {
            var entitySet = new Model.FlashcardSet
            {
                DateModified = dtoSet.DateModified,
                FlashcardSetId = dtoSet.Id,
                IsPublic = dtoSet.IsPublic,
                CreatorId = dtoSet.Creator.ID,
                Name = dtoSet.Name,
                Tags = dtoSet.Tags,
                CategoryId = dtoSet.Category.Id
            };

            foreach (var dtoItem in dtoSet.Flashcards)
                entitySet.Flashcards.Add(dtoItem.ToEntity());

            return entitySet;
        }

        #endregion

        #region Updates

        public static void UpdateFromDto(this Model.FlashcardPart entityPart, FlashcardPart dtoPart)
        {
            entityPart.DateModified = dtoPart.DateModified;
            entityPart.TypeId = dtoPart.Type.Id;
            entityPart.Data = dtoPart.Data;
        }

        public static void UpdateFromDto(this Model.Flashcard entityCard, Flashcard dtoCard)
        {
            entityCard.DateModified = dtoCard.DateModified;
            entityCard.Definition.UpdateFromDto(dtoCard.Definition);
            entityCard.Term.UpdateFromDto(dtoCard.Term);
        }

        public static void UpdateFromDto(this Model.FlashcardSet entitySet, FlashcardSet dtoSet, ref List<Model.Flashcard> cardsToRemove)
        {
            entitySet.DateModified = dtoSet.DateModified;
            entitySet.IsPublic = dtoSet.IsPublic;
            entitySet.Name = dtoSet.Name;
            entitySet.Tags = dtoSet.Tags;
            entitySet.CategoryId = dtoSet.Category.Id;

            cardsToRemove = new List<Model.Flashcard>();

            foreach (var entityCard in entitySet.Flashcards)
            {
                if (dtoSet.Flashcards.FirstOrDefault(x => x.Id == entityCard.FlashcardId) == null)
                    cardsToRemove.Add(entityCard);
            }

            foreach (var cardToRemove in cardsToRemove)
                entitySet.Flashcards.Remove(cardToRemove);

            var flashcardsToAdd = new List<Model.Flashcard>();

            foreach (var dtoCard in dtoSet.Flashcards)
            {
                var entityCard = entitySet.Flashcards.FirstOrDefault(x => x.FlashcardId == dtoCard.Id);
                if (entityCard != null)
                {
                    entityCard.UpdateFromDto(dtoCard);
                }
                else
                {
                    //entitySet.Flashcards.Add(dtoCard.ToEntity());
                    flashcardsToAdd.Add(dtoCard.ToEntity());
                }
            }

            foreach (var item in flashcardsToAdd)
                entitySet.Flashcards.Add(item);
        }

        #endregion

        #endregion

        #region ENTITY to DTO

        public static Category ToDto(this Model.Category entityCategory)
        {
            var dtoCategory = new Category
            {
                Id = entityCategory.CategoryId,
                Name = entityCategory.Name,
                ParentId = entityCategory.ParentCategoryId,
                Language = entityCategory.Language
            };
            return dtoCategory;
        }

        public static FlashcardPartType ToDto(this Model.FlashcardPartType entityType)
        {
            var dtoType = new FlashcardPartType
            {
                Id = entityType.FlashcardPartTypeId,
                Name = entityType.Name
            };
            return dtoType;
        }

        public static FlashcardPart ToDto(this Model.FlashcardPart entityPart, List<FlashcardPartType> partTypes)
        {
            var dtoPart = new FlashcardPart()
            {
                Id = entityPart.FlashcardPartId,
                DateModified = entityPart.DateModified.Value,
                Data = entityPart.Data,
                Type = partTypes.FirstOrDefault(x => x.Id == entityPart.TypeId),
            };
            return dtoPart;
        }

        public static Flashcard ToDto(this Model.Flashcard entityCard, List<FlashcardPartType> partTypes)
        {
            var dtoCard = new Flashcard()
            {
                Id = entityCard.FlashcardId,
                DateModified = entityCard.DateModified.Value,
                FlashcardSetId = entityCard.FlashcardSetId,
                Definition = entityCard.Definition.ToDto(partTypes),
                Term = entityCard.Term.ToDto(partTypes)
            };
            return dtoCard;
        }

        public static FlashcardSet ToDto(this Model.FlashcardSet entitySet, List<FlashcardPartType> partTypes)
        {
            var dtoSet = new FlashcardSet()
            {
                Id = entitySet.FlashcardSetId,
                DateModified = entitySet.DateModified.Value,
                IsPublic = entitySet.IsPublic,
                Name = entitySet.Name,
                Tags = entitySet.Tags,
                Category = entitySet.Category.ToDto(),
                Flashcards = new List<Flashcard>()
            };

            foreach (var item in entitySet.Flashcards)
                dtoSet.Flashcards.Add(item.ToDto(partTypes));

            return dtoSet;
        }

        public static RepeatItem ToDto(this Model.RepeatItem entityItem)
        {
            var dtoItem = new RepeatItem()
            {
                RepeatItemId = entityItem.RepeatItemId,
                RepeatMark = entityItem.RepeatMark,
                FlashcardId = entityItem.FlashcardId
            };

            return dtoItem;
        }

        public static NetworkResult ToDto(this Model.NeuralNetworkResults entityResult)
        {
            var dtoItem = new NetworkResult
            {
                FlashcardID = entityResult.FlashcardID,
                Unknown = (double)entityResult.Unknown,
                Poor = (double)entityResult.Poor,
                Average = (double)entityResult.Average,
                Good = (double)entityResult.Good,
                UserMark = entityResult.UserMark
            };

            return dtoItem;
        }

        #endregion
    }
}